<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>3.匿名函数与函数提升</title>
</head>

<body>
  <script>

    // 函数提升 
    // 1. 如果使用变量定义了一个函数，则不能在定义该方法前使用该函数
    // 2. 没有用变量定义函数的话会存在函数提升，可以在页面任意地方使用

    // 函数提升，如果使用变量定义了一个函数，则不能在定义该方法前使用该函数
    // show(); // 此行代码报错
    var show = function () {
      console.log("用变量定义函数");
    };

    show();

    // 没有用变量定义函数的话会存在函数提升，可以在页面任意地方使用
    log();
    function log () {
      console.log("全局函数");
    }
    log();

    // 匿名函数
    //函数是对象所以可以通过赋值来指向到函数对象的指针，当然指针也可以传递给其他变量，注意后面要以;结束。下面使用函数表达式将 匿名函数 赋值给变量

    let hd = function (num) {
      return ++num;
    };

    console.log(hd instanceof Object); //true

    let cms = hd;
    console.log(cms(3)); //4
    /*
    标准声明的函数优先级更高，解析器会优先提取函数并放在代码树顶端，所以标准声明函数位置不限制，所以下面的代码可以正常执行。
    */
    //标准声明优先级高于赋值声明
    console.log(hd2(3));//4
    function hd2 (num) {
      return ++num;
    };
    var hd2 = function () {
      return "hd";
    };
    //程序中使用匿名函数的情况非常普遍 
    function sum (...args) { 
      return args.reduce((a, b) => a + b);
    }
    console.log(sum(1, 2, 3)); //6
  </script>
</body>

</html>